import { Matrix4, Mesh, Vector3 } from "three";
import Frame from "../model/gameObject/Frame";
import Scene from "../model/gameObject/Scene";
import Camera from "./Camera";
import loadShader from "./loadShader";
import MyView from "../model/Mesh/MyView";
import MeshLD from "../model/Mesh/MeshLD";

interface AppData {
    canvas: HTMLCanvasElement;
}

export default class GameApplication {
    public static app: GameApplication;
    public scene: Scene;
    public frame: Frame;
    public canvas: HTMLCanvasElement;

    public gl: any;
    private cameraMap: Map<string, Camera>;

    public constructor(data: AppData) {
        GameApplication.app = this;

        this.canvas = data.canvas;
        this.gl = this.canvas.getContext("webgl", { antialias: true, });
        this.frame = new Frame('frame', this.gl);
        this.scene = new Scene('scene', this.gl);
        this.cameraMap = new Map();
    }

    public init() {
        const { gl, cameraMap, scene, frame } = this;
        cameraMap.set('default', new Camera({
            eye: new Vector3(0, 5, 0),
            lookAt: new Vector3(0, 0, 0),
            canvas: this.canvas
        }));
        new loadShader(gl, frame, scene);
        this._initScene();
        this._initFrame();
    }

    private _initScene() {
        const { scene, gl } = this;

        scene.init();

        const view = new MyView('view');
        scene.add(view);
    }

    private _initFrame() {
        const { frame, gl } = this;

        frame.init();
    }

    private update(time: number) {
        const { scene, frame } = this;

        frame.update(time);
        scene.update(time);

        frame.draw();
        frame.setTexture();
        const texture = frame.drawLast();//这个吊警告我是真的不知道怎么弄了

        scene.updateView(texture);
        scene.draw();


        requestAnimationFrame(() => {
            this.update(time);
        })
    }

    public static getCamera(name: string = 'default') {
        const { cameraMap } = GameApplication.app;
        return cameraMap.get(name);
    }

    public GameStart() {
        this.update(0);
    }

    public GameOver() {

    }
}